-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local class = require 'mc.class'
local c_handler_base = require 'bma.handles.handler_base'
local c_optical_module = require 'device.class.optical_module'
local c_handler_optical = require 'bma.handles.handler_optical'
local singleton = require 'mc.singleton'
local update_if_valid = c_handler_base.update_if_valid

local get_odata_id = c_handler_base.get_odata_id

local c_handler_optical_diag = class(c_handler_base)

function c_handler_optical_diag:ctor()
end

function c_handler_optical_diag:init()
    self:regist_odata_type('OemEthernetInterfaceSffDiagnostic')
    self:regist_odata_type('OemInfiniBandSffDiagnostic')
    self:regist_odata_type('OemFCSffDiagnostic')

    self:regist_class_type(c_optical_module)

    c_handler_optical.get_instance().on_need_update:on(function(object, path)
        self:match_resource(object, path)
    end)
end

function c_handler_optical_diag:find_object(_, data)
    local optical_bma_id = self.get_parent_path(get_odata_id(data))
    return c_handler_optical.get_instance():get_object(optical_bma_id)
end

function c_handler_optical_diag:update_optical_diag(op, data)
    op.get_diagnostic_by_ibma_success = true
    if op and op:check_port_workload_type() then
        return
    end
    op.Presence = 1
    -- bmc.kepler.Systems.OpticalModule.Temperature
    op.ReadingCelsius = update_if_valid(op.ReadingCelsius, data.TempCurrentCelsius)
    op.TemperatureUpperThresholdCritical = update_if_valid(op.TemperatureUpperThresholdCritical,
        data.TempHighAlarmCelsius)
    op.TemperatureLowerThresholdCritical = update_if_valid(op.TemperatureLowerThresholdCritical,
        data.TempLowAlarmCelsius)

    -- bmc.kepler.Systems.OpticalModule.Voltage
    op.SupplyVoltage = update_if_valid(op.SupplyVoltage, data.VccCurrentVolts)
    op.VoltageUpperThresholdCritical = update_if_valid(op.VoltageUpperThresholdCritical,
        data.VccHighAlarmVolts)
    op.VoltageLowerThresholdCritical = update_if_valid(op.VoltageLowerThresholdCritical,
        data.VccLowAlarmVolts)

    -- bmc.kepler.Systems.OpticalModule.BiasCurrent
    op.TXBiasCurrentMilliAmps = update_if_valid(op.TXBiasCurrentMilliAmps,
        data.TxBiasCurrentMilliampere)
    op.BC_TXUpperThresholdCritical = update_if_valid(op.BC_TXUpperThresholdCritical,
        data.TxBiasHighAlarmMilliampere)
    op.BC_TXLowerThresholdCritical = update_if_valid(op.BC_TXLowerThresholdCritical,
        data.TxBiasLowAlarmMilliampere)

    -- bmc.kepler.Systems.OpticalModule.Power
    op.TXOutputPowerMilliWatts = update_if_valid(op.TXOutputPowerMilliWatts,
        data.TxPowerCurrentMilliwatt)
    op.Power_TXUpperThresholdCritical = update_if_valid(op.Power_TXUpperThresholdCritical,
        data.TxPowerHighAlarmMilliwatt)
    op.Power_TXLowerThresholdCritical = update_if_valid(op.Power_TXLowerThresholdCritical,
        data.TxPowerLowAlarmMilliwatt)
    op.RXInputPowerMilliWatts = update_if_valid(op.RXInputPowerMilliWatts,
        data.RxPowerCurrentMilliwatt)
    op.RXUpperThresholdCritical = update_if_valid(op.RXUpperThresholdCritical,
        data.RxPowerHighAlarmMilliwatt)
    op.RXLowerThresholdCritical = update_if_valid(op.RXLowerThresholdCritical,
        data.RxPowerLowAlarmMilliwatt)
end

function c_handler_optical_diag:reset()
    for object, _ in pairs(self.objects) do
        object:reset_bma_stats()
    end
end

function c_handler_optical_diag:add(_, data, object)
    self:update_optical_diag(object, data)
end

function c_handler_optical_diag:update(_, data, object)
    self:update_optical_diag(object, data)
end

return singleton(c_handler_optical_diag)
